package com.webservice;

import com.carpark.ejb.DAO.DAO;
import com.carpark.ejb.DAO.DaoImpl;
import com.carpark.ejb.Model.AccountingdataModel;
import com.carpark.ejb.Model.CarsModel;
import com.carpark.ejb.Model.ClientsModel;
import java.io.Serializable;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.faces.application.Application;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.primefaces.event.RowEditEvent;
import validator.ValidationBean;

/**
 *
 * @author Krzysztof
 */
@ManagedBean
@ViewScoped
public class AccountingDataBean implements Serializable {

    private static final long serialVersionUID = 1L;
  private final DAO dao = getSingleDao();
    DaoSingleObject dso;
    private Integer accountingDataId;
    ClientsModel currentUser;
    AccountingdataModel currentAc;
    List<AccountingdataModel> accountingDataByClient;
      List<AccountingdataModel> accountingDataForPasses;
    @Size(min = 1, max = 255)
    private String name;
    @Size(min = 1, max = 255)
    private String city;
    @Size(min = 1, max = 15)
    private String zipNumber;
    @Size(min = 1, max = 255)
    private String street;
    @Size(min = 1, max = 15)
    private String houseNumber;
    @Size(max = 15)
    private String localNumber;
    @Size(max = 13)
    private String nipNumber;
    // @Pattern(regexp="^\\(?(\\d{3})\\)?[- ]?(\\d{3})[- ]?(\\d{4})$", message="Invalid phone/fax format, should be as xxx-xxx-xxxx")//if the field contains phone or fax number consider using this annotation to enforce field validation
    @Size(max = 15)
    private String phone;
    @Size(min = 1, max = 13)
    private String payerType;
    @Size(max = 100)
    private String comments;
    private LoginBean lg;
    private SelectItem[] payerOptions;
    @Size(min = 1, max = 255)
    private String nameED;
    @Size(min = 1, max = 255)
    private String cityED;
    @Size(min = 1, max = 15)
    private String zipNumberED;
    @Size(min = 1, max = 255)
    private String streetED;
    @Size(min = 1, max = 15)
    private String houseNumberED;
    @Size(max = 15)
    private String localNumberED;
    @Size(max = 13)
    private String nipNumberED;
    // @Pattern(regexp="^\\(?(\\d{3})\\)?[- ]?(\\d{3})[- ]?(\\d{4})$", message="Invalid phone/fax format, should be as xxx-xxx-xxxx")//if the field contains phone or fax number consider using this annotation to enforce field validation
    @Size(max = 15)
    private String phoneED;
    @Size(min = 1, max = 13)
    private String payerTypeED;
    @Size(max = 100)
    private String commentsED;
    SelectItem[] accByClientOptions;
    
    
    @PostConstruct
    public void init() {

        setCurrentUser(dao.getClientById(getUserID()));

        payerOptions = createFilterOptionsForPayerType();
        accByClientOptions=createSelectItemsAccByClient();
    }

    public Integer getUserID() {
        if (this.lg == null) {
            FacesContext context = FacesContext.getCurrentInstance();
            Application app = context.getApplication();
            this.lg = (LoginBean) app.evaluateExpressionGet(context, "#{loginBean}", LoginBean.class);
        }
        return this.lg.getId();
    }

    public ClientsModel getCurrentUser() {
        return currentUser;
    }
      public DAO getSingleDao() {
        if (this.dso == null) {
            FacesContext context = FacesContext.getCurrentInstance();
            Application app = context.getApplication();
            this.dso = (DaoSingleObject) app.evaluateExpressionGet(context, "#{daoSingleObject}", DaoSingleObject.class);
        }
        return this.dso.dao;
    }
 private SelectItem[] createSelectItemsAccByClient() {
        List<AccountingdataModel> accs = getAllByClient();
        SelectItem[] options = new SelectItem[accs.size() + 1];

        options[0] = new SelectItem(null, "Wszystkie przepustki");
        int i = 1;
        for (AccountingdataModel acc : accs) {
            options[i] = new SelectItem(acc.getAccountingDataId(), acc.getName()+" "+acc.getCity()+" "+getLabelFromPayerValue(acc) );
            i++;
        }

        return options;

    }
    public SelectItem[] getPayerOptions() {
        return payerOptions;
    }

    public SelectItem[] getAccByClientOptions() {
        return accByClientOptions;
    }

    public void setAccByClientOptions(SelectItem[] accByClientOptions) {
        this.accByClientOptions = accByClientOptions;
    }

    public void setCurrentUser(ClientsModel currentUser) {
        this.currentUser = currentUser;
    }

    public LoginBean getLg() {
        return lg;
    }

    public void setLg(LoginBean lg) {
        this.lg = lg;
    }

    public Integer getAccountingDataId() {
        return accountingDataId;
    }

    public void setAccountingDataId(Integer accountingDataId) {
        this.accountingDataId = accountingDataId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getZipNumber() {
        return zipNumber;
    }

    public void setZipNumber(String zipNumber) {
        this.zipNumber = zipNumber;
    }

    public String getStreet() {
        return street;
    }

    

    public void setAccountingDataForPasses(List<AccountingdataModel> accountingDataForPasses) {
        this.accountingDataForPasses = accountingDataForPasses;
    }

    public void setStreet(String street) {
        this.street = street;
    }

    public String getHouseNumber() {
        return houseNumber;
    }

    public void setHouseNumber(String houseNumber) {
        this.houseNumber = houseNumber;
    }

    public String getLocalNumber() {
        return localNumber;
    }

    public void setLocalNumber(String localNumber) {
        this.localNumber = localNumber;
    }

    public String getNipNumber() {
        return nipNumber;
    }

    public void setNipNumber(String nipNumber) {
        this.nipNumber = nipNumber;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getPayerType() {
        return payerType;
    }

    public void setPayerType(String payerType) {
        this.payerType = payerType;
    }

    public String getComments() {
        return comments;
    }

    public void setComments(String comments) {
        this.comments = comments;
    }

    public AccountingdataModel getCurrentAc() {
        return currentAc;
    }

    public void setCurrentAc(AccountingdataModel currentAc) {
        this.currentAc = currentAc;
    }

    public List<AccountingdataModel> getAccountingDataByClient() {
        return accountingDataByClient;
    }

    public void setAccountingDataByClient(List<AccountingdataModel> accountingDataByClient) {
        this.accountingDataByClient = accountingDataByClient;
    }

    public final void loadAllValuesFromDatabase() {
        this.city = currentAc.getCity();
        this.comments = currentAc.getComments();
        this.houseNumber = currentAc.getHouseNumber();
        this.localNumber = currentAc.getLocalNumber();
        this.name = currentAc.getName();
        this.nipNumber = currentAc.getNipNumber();
        this.payerType = currentAc.getPayerType();
        this.phone = currentAc.getPhone();
        this.street = currentAc.getStreet();
        this.zipNumber = currentAc.getZipNumber();

    }

    public final void setAllValues(AccountingdataModel to, AccountingdataModel from) {
        to.setCity(from.getCity());
        to.setComments(from.getComments());
        to.setHouseNumber(from.getHouseNumber());
        to.setLocalNumber(from.getLocalNumber());
        to.setName(from.getName());
        to.setNipNumber(from.getNipNumber());
        to.setPayerType(from.getPayerType());
        to.setPhone(from.getPhone());
        to.setStreet(from.getStreet());
        to.setZipNumber(from.getZipNumber());

    }

    public AccountingdataModel updateAccounting(Integer idAcc, AccountingdataModel readed) {

        Logger.getLogger(AccountingDataBean.class.getName()).log(Level.SEVERE, "[CarPark] Updating accountingData ");

        AccountingdataModel am = dao.getAccountingDataById(idAcc);
        setAllValues(am, readed);

        return dao.updateAccountingdata(am);

    }

    public void onEdit(RowEditEvent event) {
          FacesMessage msg;
        Integer id = ((AccountingdataModel) event.getObject()).getAccountingDataId();
        if (updateAccounting(id, ((AccountingdataModel) event.getObject()))==null){
            msg = new FacesMessage("Dane niepoprawne, spróbuj ponownie podać dane dla: ", ((AccountingdataModel) event.getObject()).getName() + "");
        }else{
         msg = new FacesMessage("Zmieniono dane", ((AccountingdataModel) event.getObject()).getName() + "");}
        FacesContext.getCurrentInstance().addMessage(null, msg);

    }
    
    public void onCancel(RowEditEvent event) {
        FacesMessage msg = new FacesMessage("Nie udało się dokonać zmian", ((AccountingdataModel) event.getObject()).getName());

        FacesContext.getCurrentInstance().addMessage(null, msg);
    }

    public List<AccountingdataModel> getAllByClient() {
        if (accountingDataByClient == null) {
            this.accountingDataByClient = dao.getAccountingDataByClient(currentUser);
        }
        return this.accountingDataByClient;

    }

    public String getLabelFromPayerValue(AccountingdataModel ac) {
        for (int i = 0; i < payerOptions.length; i++) {
            if (payerOptions[i].getValue().equals(ac.getPayerType())) {
                return payerOptions[i].getLabel();
            }
        }
        return "brak";
    }

    private SelectItem[] createFilterOptionsForPayerType() {
        SelectItem[] options = new SelectItem[3];

        options[0] = new SelectItem("", "Wybierz");

        options[1] = new SelectItem(Payer.COMPANY.getPayerTypeName(), Payer.COMPANY.getLabel());
        options[2] = new SelectItem(Payer.PRIVATE_PERSON.getPayerTypeName(), Payer.PRIVATE_PERSON.getLabel());

        return options;

    }
}
